www.gusucode.com > VC++ 以多种方式处理位图文件的例子源码程序 > VC++ 以多种方式处理位图文件的例子源码程序\code\dibimage.cpp
//Download by http://www.NewXing.com /* Module : DIBIMAGE.CPP Purpose: Implementation for an MFC class that encapsulates DIBs and supports a variety of image manipulation functions on it Created: PJN / DIBSECTION/1 / 23-07-1997 History: None Copyright (c) 1997 by PJ Naughter. All rights reserved. */ ///////////////////////////////// Includes ////////////////////////////////// #include "stdafx.h" #include "math.h" #include "dibimage.h" #include "resource.h" ////////////////////////////// Future additions /////////////////////////////// /* BOOL CDibImage::TraceContourFilter() BOOL CDibImage::EqualizeHistogram() BOOL CDibImage::StretchHistogram() BOOL CDibImage::MosaicFilter(int BlockSize) BOOL CDibImage::DespeckleFilter() BOOL CDibImage::DilateFilter() BOOL CDibImage::EmbossFilter() BOOL CDibImage::ErodeFilter() BOOL CDibImage::SoftenFilter() BOOL CDibImage::SharpenFilter() BOOL CDibImage::UnSharpenFilter() BOOL CDibImage::Posterize(int BitsPerChannel) BOOL CDibImage::Solerize(int Threshold) BOOL CDibImage::CirleDeform() BOOL CDibImage::HorizontalCylinderDeform() BOOL CDibImage::VerticalCylinderDeform() BOOL CDibImage::MotionBlurDeform() BOOL CDibImage::PentagonDeform() BOOL CDibImage::PerspectiveHorizontalDeform() BOOL CDibImage::PerspectiveVerticalDeform() BOOL CDibImage::PinchDeform() BOOL CDibImage::PunchDeform() BOOL CDibImage::SkewDeform() BOOL CDibImage::WindDeform() BOOL CDibImage::ModifyHistogram(int* TransformTable, int nSize); BOOL CDibImage::Resize(const CSize& size); BOOL CDibImage::Resample(const CSize& size); static BOOL CDibImage::ArithmeticAdd(CDibImage& dib1, CDibImage& dib2, int Divisor, int Bias, BOOL bClip); static BOOL CDibImage::ArithmeticSubtract(CDibImage& dib1, CDibImage& dib2, int Divisor, int Bias, BOOL bClip); static BOOL CDibImage::ArithmeticMultiply(CDibImage& dib1, CDibImage& dib2, int Divisor, int Bias, BOOL bClip); static BOOL CDibImage::ArithmeticDifference(CDibImage& dib1, CDibImage& dib2, int Divisor, int Bias, BOOL bClip); static BOOL CDibImage::ArithmeticDarkest(CDibImage& dib1, CDibImage& dib2, int Divisor, int Bias, BOOL bClip); static BOOL CDibImage::ArithmeticLightest(CDibImage& dib1, CDibImage& dib2, int Divisor, int Bias, BOOL bClip); BOOL CDibImage::SpacialFilter(); */ ///////////////////////////////// defines ///////////////////////////////////// #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //////////////////////////////// Implementation /////////////////////////////// C3By3Filter::C3By3Filter() { //Default filter is a filter which will not do anything to the image for (int i=0; i<3; i++) for (int j=0; j<3; j++) m_nValues[i][j] = 0; m_nValues[1][1] = 1; m_nDivision = 1; m_nBias = 0; } COLORREF C3By3Filter::Filter(CDibImage& dibImage, LPSTR lpDibBits, int x, int y) { int r = 0; int g = 0; int b = 0; for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { COLORREF c; if (dibImage.GetPixel(x+i-1, y+j-1, c, lpDibBits)) { r += (m_nValues[i][j] * GetRValue(c)); g += (m_nValues[i][j] * GetGValue(c)); b += (m_nValues[i][j] * GetBValue(c)); } } } ASSERT(m_nDivision); r = min(r/m_nDivision + m_nBias, 255); g = min(g/m_nDivision + m_nBias, 255); b = min(b/m_nDivision + m_nBias, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); return RGB(r, g, b); } C3By3MedianFilter::C3By3MedianFilter() { } COLORREF C3By3MedianFilter::Filter(CDibImage& dibImage, LPSTR lpDibBits, int x, int y) { int nPixels = 0; for (int k=0; k<9; k++) m_Ordered[k] = 0; for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { COLORREF c; if (dibImage.GetPixel(x+i-1, y+j-1, c, lpDibBits)) { m_Ordered[nPixels] = c; nPixels++; } } } qsort(&m_Ordered, nPixels, sizeof(COLORREF), CompareFunc); return m_Ordered[nPixels/2]; } int C3By3MedianFilter::CompareFunc(const void *elem1, const void *elem2) { COLORREF c1 = *(COLORREF*)elem1; COLORREF c2 = *(COLORREF*)elem2; if (c1 == c2) return 0; else { BYTE r1 = GetRValue(c1); BYTE g1 = GetGValue(c1); BYTE b1 = GetBValue(c1); BYTE r2 = GetRValue(c2); BYTE g2 = GetGValue(c2); BYTE b2 = GetBValue(c2); if ((r1 + g1 + b1) > (r2 + g2 + b2)) return 1; else return -1; } } C5By5Filter::C5By5Filter() { //Default filter is a filter which will not do anything to the image for (int i=0; i<5; i++) for (int j=0; j<5; j++) m_nValues[i][j] = 0; m_nValues[2][2] = 1; m_nDivision = 1; m_nBias = 0; } COLORREF C5By5Filter::Filter(CDibImage& dibImage, LPSTR lpDibBits, int x, int y) { int r = 0; int g = 0; int b = 0; for (int i=0; i<5; i++) { for (int j=0; j<5; j++) { COLORREF c; if (dibImage.GetPixel(x+i-2, y+j-2, c, lpDibBits)) { r += (m_nValues[i][j] * GetRValue(c)); g += (m_nValues[i][j] * GetGValue(c)); b += (m_nValues[i][j] * GetBValue(c)); } } } ASSERT(m_nDivision); r = min(r/m_nDivision + m_nBias, 255); g = min(g/m_nDivision + m_nBias, 255); b = min(b/m_nDivision + m_nBias, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); return RGB(r, g, b); } C7By7Filter::C7By7Filter() { //Default filter is a filter which will not do anything to the image for (int i=0; i<7; i++) for (int j=0; j<7; j++) m_nValues[i][j] = 0; m_nValues[3][3] = 1; m_nDivision = 1; m_nBias = 0; } COLORREF C7By7Filter::Filter(CDibImage& dibImage, LPSTR lpDibBits, int x, int y) { int r = 0; int g = 0; int b = 0; for (int i=0; i<7; i++) { for (int j=0; j<7; j++) { COLORREF c; if (dibImage.GetPixel(x+i-3, y+j-3, c, lpDibBits)) { r += (m_nValues[i][j] * GetRValue(c)); g += (m_nValues[i][j] * GetGValue(c)); b += (m_nValues[i][j] * GetBValue(c)); } } } ASSERT(m_nDivision); r = min(r/m_nDivision + m_nBias, 255); g = min(g/m_nDivision + m_nBias, 255); b = min(b/m_nDivision + m_nBias, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); return RGB(r, g, b); } CUndoNode::CUndoNode(CDibImage* pImage, const CString& sDescription) { m_pImage = pImage; m_sDescription = sDescription; } CUndoNode::~CUndoNode() { delete m_pImage; m_pImage = NULL; } CDibImage::CDibImage() { m_hDib = NULL; m_pWorkingArea = NULL; m_nWidth = 0; m_nHeight = 0; m_nScanWidth = 0; m_nBitsPerPixel = 0; m_Pal = NULL; m_nUndoSize = 4; //By default, we support 4 levels of undo, if you //want more (at the expense of memory usage) just //call SetUndoSize will the level you want } CDibImage::CDibImage(const CDibImage& ds) { m_hDib = NULL; m_pWorkingArea = NULL; m_nWidth = 0; m_nHeight = 0; m_nScanWidth = 0; m_nBitsPerPixel = 0; m_Pal = NULL; m_nUndoSize = 4; //By default, we support 4 levels of undo, if you //want more (at the expense of memory usage) just //call SetUndoSize will the level you want Attach((HDIB) CopyHandle(ds.m_hDib)); SetWorkingArea(ds.m_pWorkingArea->Clone()); } CDibImage::~CDibImage() { Destroy(); //empty the redo stack for (int i=0; i<m_RedoStack.GetSize(); i++) { CUndoNode* pNode = m_RedoStack.GetAt(i); delete pNode; pNode = NULL; } m_RedoStack.SetSize(0); //empty the undo stack for (i=0; i<m_UndoStack.GetSize(); i++) { CUndoNode* pNode = m_UndoStack.GetAt(i); delete pNode; pNode = NULL; } m_UndoStack.SetSize(0); } CDibImage& CDibImage::operator=(const CDibImage& ds) { Attach((HDIB) CopyHandle(ds.m_hDib)); SetWorkingArea(ds.m_pWorkingArea->Clone()); return *this; } BOOL CDibImage::Create(CSize size, WORD nBitCount) { Destroy(); BOOL bSuccess = TRUE; CWindowDC dcScreen(NULL); // should not already have palette ASSERT(m_Pal == NULL); // Select specified palette m_Pal = ::CreateHalftonePalette(dcScreen.m_hDC); if (m_Pal == NULL) return FALSE; // Fill in the BITMAPINFO Structure BITMAPINFO bmi; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = size.cx; bmi.bmiHeader.biHeight = size.cy; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = nBitCount; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; bmi.bmiHeader.biXPelsPerMeter = 0; bmi.bmiHeader.biYPelsPerMeter = 0; int nPaletteSize = ComputePaletteSize(nBitCount); bmi.bmiHeader.biClrUsed = nPaletteSize; bmi.bmiHeader.biClrImportant = nPaletteSize; m_nWidth = size.cx; m_nHeight = size.cy; m_nBitsPerPixel = nBitCount; m_nScanWidth = WIDTHBYTES(m_nWidth*m_nBitsPerPixel); m_pWorkingArea = new CRectWorkingArea(Rect()); DWORD dwSize = sizeof(bmi) + m_nScanWidth*m_nHeight; m_hDib = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize); if (m_hDib == NULL) return FALSE; LPSTR pDib = (LPSTR) ::GlobalLock((HGLOBAL) m_hDib); memcpy(pDib, &bmi, sizeof(bmi)); ::GlobalUnlock((HGLOBAL) m_hDib); return bSuccess; } int CDibImage::ComputePaletteSize(DWORD nBitCount) { int nSize = 0; switch(nBitCount) { case 1: nSize = 2; break; case 4: nSize = 16; break; case 8: nSize = 256; break; case 16: case 24: case 32: nSize = 0; break; default: ASSERT(FALSE); break; } return nSize; } void CDibImage::Destroy() { if (m_pWorkingArea) { delete m_pWorkingArea; m_pWorkingArea = NULL; } if (m_hDib) GlobalFree(m_hDib); DeleteObject(m_Pal); } BOOL CDibImage::Attach(HGLOBAL hGlobal) { Destroy(); BOOL bSuccess = FALSE; if (hGlobal) { m_hDib = (HDIB) hGlobal; DWORD dwSize = GlobalSize(m_hDib); ASSERT(dwSize); LPSTR lpDib = (LPSTR) ::GlobalLock(m_hDib); ASSERT(lpDib); m_nWidth = ::DIBWidth(lpDib); m_nHeight = ::DIBHeight(lpDib); ::GlobalUnlock((HGLOBAL) m_hDib); m_nBitsPerPixel = GetBitsPerPixel(); m_nScanWidth = WIDTHBYTES(m_nWidth*m_nBitsPerPixel); m_pWorkingArea = new CRectWorkingArea(Rect()); CPalette pal; ::CreateDIBPalette(m_hDib, &pal); m_Pal = (HPALETTE) pal.Detach(); bSuccess = TRUE; } return bSuccess; } BOOL CDibImage::Load(LPCTSTR lpszPathName) { CFile f; if (!f.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite)) return FALSE; return Attach(::ReadDIBFile(f)); } BOOL CDibImage::Load(HINSTANCE hInst, LPCTSTR lpResourceName) { HRSRC hSrc = FindResource(hInst, lpResourceName, RT_BITMAP); BOOL bSuccess = FALSE; if (hSrc) { HGLOBAL hResData = LoadResource(hInst, hSrc); if (hResData) { LPVOID lpResData = LockResource(hResData); if (lpResData) { DWORD dwSize = SizeofResource(hInst, hSrc); if (dwSize) { HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwSize); if (hGlobal) { LPVOID lpBitmapData = GlobalLock(hGlobal); if (lpBitmapData) { CopyMemory(lpBitmapData, lpResData, dwSize); GlobalUnlock(hGlobal); bSuccess = Attach(hGlobal); } } } } } } return bSuccess; } int CDibImage::GetBitsPerPixel() const { int nBitCount; if (m_hDib == NULL) nBitCount = 0; else { LPSTR lpDib = (LPSTR) ::GlobalLock(m_hDib); // Calculate the number of bits per pixel for the DIB. if (IS_WIN30_DIB(lpDib)) nBitCount = ((LPBITMAPINFOHEADER)lpDib)->biBitCount; else nBitCount = ((LPBITMAPCOREHEADER)lpDib)->bcBitCount; ::GlobalUnlock((HGLOBAL) m_hDib); } return nBitCount; } BOOL CDibImage::Draw(CDC& dc, const CRect* rcDst, const CRect* rcSrc, CPalette* pPal) { CRect DCRect(Rect()); if (rcDst) DCRect = *rcDst; CRect DibRect(Rect()); if (rcSrc) DibRect = *rcSrc; CPalette pal; pal.Attach(m_Pal); CPalette* pPalette = NULL; if (pPal) pPalette = pPal; else pPalette = &pal; BOOL bSuccess = ::PaintDIB(dc.m_hDC, &DCRect, m_hDib, &DibRect, pPalette); pal.Detach(); return bSuccess; } BOOL CDibImage::GetPixel(int x, int y, COLORREF& value, LPSTR lpDibBits) const { if (m_hDib == NULL) return FALSE; //Currently only support pixel access for 24 bit images //May support other formats in the future if (m_nBitsPerPixel != 24) return FALSE; //position is out of range if (x >= m_nWidth || x < 0 || y >= m_nHeight || y < 0) return FALSE; BOOL bLocked = FALSE; if (lpDibBits == NULL) { LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); lpDibBits = ::FindDIBBits(lpDibHdr); bLocked = TRUE; } BYTE* pData = (BYTE*) lpDibBits + (m_nHeight-1-y)*m_nScanWidth + x*3; value = RGB(pData[2], pData[1], pData[0]); if (bLocked) ::GlobalUnlock((HGLOBAL) m_hDib); return TRUE; } BOOL CDibImage::SetPixel(int x, int y, const COLORREF& value, LPSTR lpDibBits) { if (m_hDib == NULL) return FALSE; //Currently only support pixel access for 24 bit images //May support other formats in the future if (m_nBitsPerPixel != 24) return FALSE; //check the position ASSERT(x < m_nWidth && x >= 0 && y < m_nHeight && y >= 0); BOOL bLocked = FALSE; if (lpDibBits == NULL) { LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); lpDibBits = ::FindDIBBits(lpDibHdr); bLocked = TRUE; } BYTE* pData = (BYTE*) lpDibBits + (m_nHeight-1-y)*m_nScanWidth + x*3; //THIS NEEDS TO BE TESTED pData[0] = GetBValue(value); pData[1] = GetGValue(value); pData[2] = GetRValue(value); if (bLocked) ::GlobalUnlock((HGLOBAL) m_hDib); return TRUE; } BOOL CDibImage::Save(LPCTSTR lpszPathName) { CFile f; if (!f.Open(lpszPathName, CFile::shareDenyWrite | CFile::modeCreate | CFile::modeWrite)) return FALSE; else return SaveDIB(m_hDib, f); } BOOL CDibImage::CopySelection(CDibImage& dib) { if (m_hDib == NULL) return FALSE; BOOL bSuccess = FALSE; ASSERT(m_pWorkingArea); CRect r = m_pWorkingArea->BoundingRectangle(); bSuccess = dib.Create(CSize(r.Width(), r.Height()), 24); if (bSuccess) { LPSTR lpDibHdrSrc = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBitsSrc = ::FindDIBBits(lpDibHdrSrc); LPSTR lpDibHdrDest = (LPSTR) ::GlobalLock(dib.m_hDib); LPSTR lpDibBitsDest = ::FindDIBBits(lpDibHdrDest); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; bSuccess = GetPixel(x, y, c, lpDibBitsSrc); bSuccess = bSuccess && dib.SetPixel(x-r.left, y-r.top, c, lpDibBitsDest); } } } GlobalUnlock((HGLOBAL) dib.m_hDib); GlobalUnlock((HGLOBAL) m_hDib); } return bSuccess; } LPSTR CDibImage::GetDIBBits() { LPSTR lpDibHdrSrc = (LPSTR) ::GlobalLock(m_hDib); return ::FindDIBBits(lpDibHdrSrc); } BOOL CDibImage::CopyToClipboard() { if (m_hDib == NULL) return FALSE; BOOL bSuccess = FALSE; if (OpenClipboard(NULL)) { if (EmptyClipboard()) { CDibImage DibCopy; bSuccess = CopySelection(DibCopy); if (bSuccess) { HDIB hNewDib = (HDIB) CopyHandle(DibCopy.m_hDib); bSuccess = (::SetClipboardData(CF_DIB, hNewDib) != NULL); } } CloseClipboard(); } return bSuccess; } BOOL CDibImage::PasteFromClipboard() { BOOL bSuccess = FALSE; if (OpenClipboard(NULL)) { HDIB hNewDib = (HDIB) CopyHandle(::GetClipboardData(CF_DIB)); CloseClipboard(); if (hNewDib != NULL) bSuccess = Attach(hNewDib); } return bSuccess; } BOOL CDibImage::PasteAvailable() { return IsClipboardFormatAvailable(CF_DIB); } void CDibImage::SetUndoSize(int nUndoSize) { m_nUndoSize = nUndoSize; if (m_nUndoSize < m_UndoStack.GetSize()) TRACE("Losing some of the undo stack in CDibImage::SetUndoSize\n"); for (int i=m_nUndoSize; i<m_UndoStack.GetSize(); i++) { CUndoNode* pNode = m_UndoStack.GetAt(i); delete pNode; } for (i=m_nUndoSize; i<m_RedoStack.GetSize(); i++) { CUndoNode* pNode = m_RedoStack.GetAt(i); delete pNode; } //Trim back the size of the arrays if necessary if (m_UndoStack.GetSize() > nUndoSize) m_UndoStack.SetSize(m_nUndoSize); if (m_RedoStack.GetSize() > nUndoSize) m_RedoStack.SetSize(m_nUndoSize); } BOOL CDibImage::SaveState(UINT nID) { CString sDescription; sDescription.LoadString(nID); return SaveState(sDescription); } BOOL CDibImage::SaveState(const CString& sDescription) { //if there is no undo stack then return immediately if (m_nUndoSize == 0) return FALSE; //If we have reached the limit of the undo stack //then drop the oldest undo by moving all the items //down in the stack if (m_UndoStack.GetSize() == m_nUndoSize) { TRACE("Undo stack size exceeded, discarding oldest\n"); CUndoNode* pNode = m_UndoStack.GetAt(0); delete pNode; for (int i=1; i<m_UndoStack.GetSize(); i++) { CUndoNode* pNode = m_UndoStack.GetAt(i); m_UndoStack.SetAt(i-1, pNode); } m_UndoStack.SetSize(m_nUndoSize-1); } CDibImage* pCopy = new CDibImage(*this); CUndoNode* pNode = new CUndoNode(pCopy, sDescription); m_UndoStack.Add(pNode); return TRUE; } BOOL CDibImage::UndoAvailable() { return (m_UndoStack.GetSize() > 0); } BOOL CDibImage::Undo() { BOOL bSuccess = FALSE; int nIndex = m_UndoStack.GetUpperBound(); if (nIndex >= 0) { //Add the current image to the redo stack CDibImage* pCopy = new CDibImage(*this); CUndoNode* pNode1 = new CUndoNode(pCopy, m_sCurrentDescription); m_RedoStack.Add(pNode1); //Remove from the undo stack and //reinstate the current value CUndoNode* pNode2 = m_UndoStack.GetAt(nIndex); operator=(*pNode2->GetImage()); pNode1->SetDescription(pNode2->GetDescription()); delete pNode2; m_UndoStack.RemoveAt(nIndex); bSuccess = TRUE; } return bSuccess; } BOOL CDibImage::Redo() { BOOL bSuccess = FALSE; int nIndex = m_RedoStack.GetUpperBound(); if (nIndex >= 0) { //Add the current image to the undo stack CDibImage* pCopy = new CDibImage(*this); CUndoNode* pNode1 = new CUndoNode(pCopy, m_sCurrentDescription); m_UndoStack.Add(pNode1); //Remove from the redo stack and //reinstate the current value CUndoNode* pNode2 = m_RedoStack.GetAt(nIndex); operator=(*pNode2->GetImage()); pNode1->SetDescription(pNode2->GetDescription()); delete pNode2; m_RedoStack.RemoveAt(nIndex); bSuccess = TRUE; } return bSuccess; } BOOL CDibImage::RedoAvailable() { return (m_RedoStack.GetSize() > 0); } CString CDibImage::UndoDescription() const { CString rVal; int nIndex = m_UndoStack.GetUpperBound(); if (nIndex >= 0) { CUndoNode* pNode = m_UndoStack.GetAt(nIndex); rVal = pNode->GetDescription(); } return rVal; } CString CDibImage::RedoDescription() const { CString rVal; int nIndex = m_RedoStack.GetUpperBound(); if (nIndex >= 0) { CUndoNode* pNode = m_RedoStack.GetAt(nIndex); rVal = pNode->GetDescription(); } return rVal; } CWorkingArea* CDibImage::GetWorkingArea() { return m_pWorkingArea; } void CDibImage::SetWorkingArea(CWorkingArea* pWorkingArea) { if (m_pWorkingArea) { delete m_pWorkingArea; m_pWorkingArea = NULL; } m_pWorkingArea = pWorkingArea; } BOOL CDibImage::SetColor(COLORREF color) { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_SETCOLOR); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) if (m_pWorkingArea->PointInSelection(CPoint(x, y))) bSuccess = SetPixel(x, y, color, lpDibBits); } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::Flip() { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_FLIP); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); int nMiddle = r.Height()/2 + r.top; for (int y=nMiddle; bSuccess && y>r.top; y--) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c1; int y1 = nMiddle + (nMiddle - y); bSuccess = GetPixel(x, y1, c1, lpDibBits); COLORREF c2; bSuccess = bSuccess && GetPixel(x, y, c2, lpDibBits); bSuccess = bSuccess && SetPixel(x, y, c1, lpDibBits); bSuccess = bSuccess && SetPixel(x, y1, c2, lpDibBits); } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::Mirror() { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_MIRROR); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); int nMiddle = r.Width()/2 + r.left; for (int x=nMiddle; bSuccess && x>r.left; x--) { for (int y=r.top; bSuccess && y<r.bottom; y++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c1; int x1 = nMiddle + (nMiddle - x); bSuccess = GetPixel(x1, y, c1, lpDibBits); COLORREF c2; bSuccess = bSuccess && GetPixel(x, y, c2, lpDibBits); bSuccess = bSuccess && SetPixel(x, y, c1, lpDibBits); bSuccess = bSuccess && SetPixel(x1, y, c2, lpDibBits); } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustBrightness(int Percentage) { if (m_hDib == NULL) return FALSE; if (Percentage < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_BRIGHTNESS); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int r = min(GetRValue(c)*Percentage/100, 255); int g = min(GetGValue(c)*Percentage/100, 255); int b = min(GetBValue(c)*Percentage/100, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); c = RGB(r, g, b); bSuccess = SetPixel(x, y, c, lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustContrast(int Percentage) { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_CONTRAST); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; bSuccess = GetPixel(x, y, c, lpDibBits); int r = min(128 + ((GetRValue(c) - 128)*Percentage/100), 255); int g = min(128 + ((GetGValue(c) - 128)*Percentage/100), 255); int b = min(128 + ((GetBValue(c) - 128)*Percentage/100), 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); c = RGB(r, g, b); bSuccess = SetPixel(x, y, c, lpDibBits); } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustGammaCorrection(float Value) { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_GAMMA); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; double MaxRange = pow((double) 255, (double) Value) / 255; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; bSuccess = GetPixel(x, y, c, lpDibBits); double dblR = pow((double) GetRValue(c), (double) Value) / MaxRange; double dblG = pow((double) GetGValue(c), (double) Value) / MaxRange; double dblB = pow((double) GetBValue(c), (double) Value) / MaxRange; int r = min((int) (dblR+0.5), 255); int g = min((int) (dblG+0.5), 255); int b = min((int) (dblB+0.5), 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); c = RGB(r, g, b); bSuccess = SetPixel(x, y, c, lpDibBits); } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustHighLight(int Percentage) { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_HIGHLIGHT); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; bSuccess = GetPixel(x, y, c, lpDibBits); int r = GetRValue(c); int g = GetGValue(c); int b = GetBValue(c); int l = r+g+b; if ((l > (170*3))) { r = min(r*Percentage/100, 255); g = min(g*Percentage/100, 255); b = min(b*Percentage/100, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); c = RGB(r, g, b); bSuccess = SetPixel(x, y, c, lpDibBits); } } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustMidtone(int Percentage) { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_MIDTONE); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; bSuccess = GetPixel(x, y, c, lpDibBits); int r = GetRValue(c); int g = GetGValue(c); int b = GetBValue(c); int l = r+g+b; if ((l >= (85*3)) && (l <= (170*3))) { r = min(r*Percentage/100, 255); g = min(g*Percentage/100, 255); b = min(b*Percentage/100, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); c = RGB(r, g, b); bSuccess = SetPixel(x, y, c, lpDibBits); } } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustShadow(int Percentage) { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_SHADOW); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; bSuccess = GetPixel(x, y, c, lpDibBits); int r = GetRValue(c); int g = GetGValue(c); int b = GetBValue(c); int l = r+g+b; if (l < (85*3)) { r = min(r*Percentage/100, 255); g = min(g*Percentage/100, 255); b = min(b*Percentage/100, 255); r = max(r, 0); g = max(g, 0); b = max(b, 0); c = RGB(r, g, b); bSuccess = SetPixel(x, y, c, lpDibBits); } } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustHue(int Percentage) { if (m_hDib == NULL) return FALSE; if (Percentage < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_HUE); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { double H; double S; double L; RGBtoHSL(c, &H, &S, &L); H = (H*Percentage/100); bSuccess = SetPixel(x, y, HLStoRGB(H, L, S), lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustSaturation(int Percentage) { if (m_hDib == NULL) return FALSE; if (Percentage < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_SATURATION); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { double H; double S; double L; RGBtoHSL(c, &H, &S, &L); S = (S*Percentage/100); bSuccess = SetPixel(x, y, HLStoRGB(H, L, S), lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustHSL(int PercentHue, int PercentSaturation, int PercentLuminosity) { if (m_hDib == NULL) return FALSE; if (PercentHue < 0) return FALSE; if (PercentSaturation < 0) return FALSE; if (PercentLuminosity < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_HSL); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { double H; double S; double L; RGBtoHSL(c, &H, &S, &L); S = (S*PercentSaturation/100); H = (H*PercentHue/100); L = (L*PercentLuminosity/100); bSuccess = SetPixel(x, y, HLStoRGB(H, L, S), lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } WORD CDibImage::GetVersion() { return 0x0101; //ie 1.01 /* Revision History 1.0 18/11/1997: Initial Public Release 1.01 10/11/1998: See help file for changes */ } void CDibImage::RGBtoHSL(COLORREF rgb, double* H, double* S, double* L) { double delta; double r = (double)GetRValue(rgb)/255; double g = (double)GetGValue(rgb)/255; double b = (double)GetBValue(rgb)/255; double cmax = max(r,max(g,b)); double cmin = min(r,min(g,b)); *L = (cmax+cmin)/2.0; if (cmax == cmin) { *S = 0; *H = 0; // it's really undefined } else { if (*L < 0.5) *S = (cmax-cmin)/(cmax+cmin); else *S = (cmax-cmin)/(2.0-cmax-cmin); delta = cmax - cmin; if (r==cmax) *H = (g-b)/delta; else if (g==cmax) *H = 2.0 +(b-r)/delta; else *H = 4.0+(r-g)/delta; *H /= 6.0; if (*H < 0.0) *H += 1; } } double CDibImage::HuetoRGB(double m1, double m2, double h) { if (h < 0) h += 1.0; if (h > 1) h -= 1.0; if (6.0*h < 1) return (m1+(m2-m1)*h*6.0); if (2.0*h < 1) return m2; if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0); return m1; } COLORREF CDibImage::HLStoRGB(const double& H, const double& L, const double& S) { double r,g,b; double m1, m2; if (S==0) { r=g=b=L; } else { if (L <= 0.5) m2 = L*(1.0+S); else m2 = L+S-L*S; m1 = 2.0*L-m2; r = HuetoRGB(m1, m2, H+1.0/3.0); g = HuetoRGB(m1, m2, H); b = HuetoRGB(m1, m2, H-1.0/3.0); } return RGB((BYTE)(r*255),(BYTE)(g*255),(BYTE)(b*255)); } BOOL CDibImage::AdjustRed(int Percentage) { if (m_hDib == NULL) return FALSE; if (Percentage < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_RED); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int r = min(GetRValue(c)*Percentage/100, 255); r = max(r, 0); c = RGB(r, GetGValue(c), GetBValue(c)); bSuccess = SetPixel(x, y, c, lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustGreen(int Percentage) { if (m_hDib == NULL) return FALSE; if (Percentage < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_GREEN); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int g = min(GetGValue(c)*Percentage/100, 255); g = max(g, 0); c = RGB(GetRValue(c), g, GetBValue(c)); bSuccess = SetPixel(x, y, c, lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::AdjustBlue(int Percentage) { if (m_hDib == NULL) return FALSE; if (Percentage < 0) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_BLUE); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int b = min(GetBValue(c)*Percentage/100, 255); b = max(b, 0); c = RGB(GetRValue(c), GetGValue(c), b); bSuccess = SetPixel(x, y, c, lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::Greyscale() { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_GREYSCALE); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int val = ((GetRValue(c) + GetGValue(c) + GetBValue(c)) / 3); bSuccess = SetPixel(x, y, RGB(val, val, val), lpDibBits); } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::Negate() { if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_ADJUST_NEGATE); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) bSuccess = SetPixel(x, y, RGB(255 - GetRValue(c), 255 - GetGValue(c), 255 - GetBValue(c)), lpDibBits); else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::FindEdgesFilter() { if (m_hDib == NULL) return FALSE; C3By3Filter Filter1; Filter1.m_nValues[0][0] = -1; Filter1.m_nValues[0][1] = 0; Filter1.m_nValues[0][2] = 1; Filter1.m_nValues[1][0] = -2; Filter1.m_nValues[1][1] = 0; Filter1.m_nValues[1][2] = 2; Filter1.m_nValues[2][0] = -1; Filter1.m_nValues[2][1] = 0; Filter1.m_nValues[2][2] = 1; C3By3Filter Filter2; Filter2.m_nValues[0][0] = -1; Filter2.m_nValues[0][1] = -2; Filter2.m_nValues[0][2] = -1; Filter2.m_nValues[1][0] = 0; Filter2.m_nValues[1][1] = 0; Filter2.m_nValues[1][2] = 0; Filter2.m_nValues[2][0] = 1; Filter2.m_nValues[2][1] = 2; Filter2.m_nValues[2][2] = 1; CDibImage dibCopy; CopySelection(dibCopy); SaveState(IDS_DI_UNDO_FILTER); ASSERT(dibCopy.m_pWorkingArea); CRect rectSrc(dibCopy.m_pWorkingArea->BoundingRectangle()); CRect rectDest(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdrSrc = (LPSTR) ::GlobalLock(dibCopy.m_hDib); LPSTR lpDibBitsSrc = ::FindDIBBits(lpDibHdrSrc); LPSTR lpDibHdrDest = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBitsDest = ::FindDIBBits(lpDibHdrDest); for (int y=0; bSuccess && y<rectSrc.Height(); y++) { for (int x=0; bSuccess && x<rectSrc.Width(); x++) { if (dibCopy.m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c1 = Filter1.Filter(dibCopy, lpDibBitsSrc, x, y); COLORREF c2 = Filter2.Filter(dibCopy, lpDibBitsSrc, x, y); int r = max(GetRValue(c1), GetRValue(c2)); int g = max(GetGValue(c1), GetGValue(c2)); int b = max(GetBValue(c1), GetBValue(c2)); bSuccess = SetPixel(x+rectDest.left, y+rectDest.top, RGB(r, g, b), lpDibBitsDest); } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::FindVerticalEdgesFilter() { C3By3Filter Filter; Filter.m_nValues[0][0] = -1; Filter.m_nValues[0][1] = -2; Filter.m_nValues[0][2] = -1; Filter.m_nValues[1][0] = 0; Filter.m_nValues[1][1] = 0; Filter.m_nValues[1][2] = 0; Filter.m_nValues[2][0] = 1; Filter.m_nValues[2][1] = 2; Filter.m_nValues[2][2] = 1; return UserDefinedFilter(Filter); } BOOL CDibImage::FindHorizontalEdgesFilter() { C3By3Filter Filter; Filter.m_nValues[0][0] = -1; Filter.m_nValues[0][1] = 0; Filter.m_nValues[0][2] = 1; Filter.m_nValues[1][0] = -2; Filter.m_nValues[1][1] = 0; Filter.m_nValues[1][2] = 2; Filter.m_nValues[2][0] = -1; Filter.m_nValues[2][1] = 0; Filter.m_nValues[2][2] = 1; return UserDefinedFilter(Filter); } BOOL CDibImage::BlurFilter() { C7By7Filter Filter; for (int i=0; i<7; i++) for (int j=0; j<7; j++) Filter.m_nValues[i][j] = 0; Filter.m_nValues[3][3] = -4; Filter.m_nValues[2][2] = 1; Filter.m_nValues[2][3] = 4; Filter.m_nValues[2][4] = 1; Filter.m_nValues[3][2] = 4; Filter.m_nValues[3][4] = 4; Filter.m_nValues[4][2] = 1; Filter.m_nValues[4][3] = 4; Filter.m_nValues[4][4] = 1; Filter.m_nDivision = 16; return UserDefinedFilter(Filter); } BOOL CDibImage::AddNoiseFilter(int Percentage) { if (Percentage <= 0 || Percentage > 100) return FALSE; if (m_hDib == NULL) return FALSE; SaveState(IDS_DI_UNDO_ADD_NOISE); ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { int test = rand(); BOOL bPass = test < (RAND_MAX*Percentage/100); if (bPass && m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; int r = rand()*256/RAND_MAX - 128; int g = rand()*256/RAND_MAX - 128; int b = rand()*256/RAND_MAX - 128; if (GetPixel(x, y, c, lpDibBits)) bSuccess = SetPixel(x, y, RGB(GetRValue(c) + r, GetGValue(c) + g, GetBValue(c) + b), lpDibBits); else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } BOOL CDibImage::MedianFilter() { C3By3MedianFilter Filter; return UserDefinedFilter(Filter); } BOOL CDibImage::UserDefinedFilter(CUserDefinedFilter& Filter) { if (m_hDib == NULL) return FALSE; CDibImage dibCopy; CopySelection(dibCopy); SaveState(IDS_DI_UNDO_FILTER); ASSERT(dibCopy.m_pWorkingArea); CRect rectSrc(dibCopy.m_pWorkingArea->BoundingRectangle()); CRect rectDest(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdrSrc = (LPSTR) ::GlobalLock(dibCopy.m_hDib); LPSTR lpDibBitsSrc = ::FindDIBBits(lpDibHdrSrc); LPSTR lpDibHdrDest = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBitsDest = ::FindDIBBits(lpDibHdrDest); for (int y=0; bSuccess && y<rectSrc.Height(); y++) { for (int x=0; bSuccess && x<rectSrc.Width(); x++) { if (dibCopy.m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c = Filter.Filter(dibCopy, lpDibBitsSrc, x, y); bSuccess = SetPixel(x+rectDest.left, y+rectDest.top, c, lpDibBitsDest); } } } GlobalUnlock((HGLOBAL) m_hDib); if (!bSuccess) Undo(); return bSuccess; } int CDibImage::ColorsUsed() const { return 0; //for the moment } BOOL CDibImage::SplitChannels(CDibImage& RedChannel, CDibImage& GreenChannel, CDibImage& BlueChannel) { if (m_hDib == NULL) return FALSE; if (!RedChannel.Create(Size(), 24)) return FALSE; if (!GreenChannel.Create(Size(), 24)) return FALSE; if (!BlueChannel.Create(Size(), 24)) return FALSE; BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); LPSTR lpDibHdrRed = (LPSTR) ::GlobalLock(RedChannel.m_hDib); LPSTR lpDibBitsRed = ::FindDIBBits(lpDibHdrRed); LPSTR lpDibHdrGreen = (LPSTR) ::GlobalLock(GreenChannel.m_hDib); LPSTR lpDibBitsGreen = ::FindDIBBits(lpDibHdrGreen); LPSTR lpDibHdrBlue = (LPSTR) ::GlobalLock(BlueChannel.m_hDib); LPSTR lpDibBitsBlue = ::FindDIBBits(lpDibHdrBlue); CRect r(Rect()); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int r = GetRValue(c); int g = GetGValue(c); int b = GetBValue(c); bSuccess = bSuccess && RedChannel.SetPixel(x, y, RGB(r, r, r), lpDibBitsRed); bSuccess = bSuccess && GreenChannel.SetPixel(x, y, RGB(g, g, g), lpDibBitsGreen); bSuccess = bSuccess && BlueChannel.SetPixel(x, y, RGB(b, b, b), lpDibBitsBlue); } else bSuccess = FALSE; } } GlobalUnlock((HGLOBAL) m_hDib); GlobalUnlock((HGLOBAL) RedChannel.m_hDib); GlobalUnlock((HGLOBAL) GreenChannel.m_hDib); GlobalUnlock((HGLOBAL) BlueChannel.m_hDib); return bSuccess; } BOOL CDibImage::GetRedChannel(CDibImage& red) { if (m_hDib == NULL) return FALSE; if (!red.Create(Size(), 24)) return FALSE; BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); LPSTR lpDibHdrRed = (LPSTR) ::GlobalLock(red.m_hDib); LPSTR lpDibBitsRed = ::FindDIBBits(lpDibHdrRed); CRect r(Rect()); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int r = GetRValue(c); bSuccess = red.SetPixel(x, y, RGB(r, r, r), lpDibBitsRed); } else bSuccess = FALSE; } } GlobalUnlock((HGLOBAL) m_hDib); GlobalUnlock((HGLOBAL) red.m_hDib); return bSuccess; } BOOL CDibImage::GetGreenChannel(CDibImage& green) { if (m_hDib == NULL) return FALSE; if (!green.Create(Size(), 24)) return FALSE; BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); LPSTR lpDibHdrGreen = (LPSTR) ::GlobalLock(green.m_hDib); LPSTR lpDibBitsGreen = ::FindDIBBits(lpDibHdrGreen); CRect r(Rect()); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int g = GetGValue(c); bSuccess = green.SetPixel(x, y, RGB(g, g, g), lpDibBitsGreen); } else bSuccess = FALSE; } } GlobalUnlock((HGLOBAL) m_hDib); GlobalUnlock((HGLOBAL) green.m_hDib); return bSuccess; } BOOL CDibImage::GetBlueChannel(CDibImage& blue) { if (m_hDib == NULL) return FALSE; if (!blue.Create(Size(), 24)) return FALSE; BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); LPSTR lpDibHdrBlue = (LPSTR) ::GlobalLock(blue.m_hDib); LPSTR lpDibBitsBlue = ::FindDIBBits(lpDibHdrBlue); CRect r(Rect()); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int b = GetBValue(c); bSuccess = blue.SetPixel(x, y, RGB(b, b, b), lpDibBitsBlue); } else bSuccess = FALSE; } } GlobalUnlock((HGLOBAL) m_hDib); GlobalUnlock((HGLOBAL) blue.m_hDib); return bSuccess; } BOOL CDibImage::CombineChannels(const CDibImage& red, const CDibImage& green, const CDibImage& blue) { if (red.m_hDib == NULL || green.m_hDib == NULL || blue.m_hDib == NULL) return FALSE; //All the images should be the same size if (red.Rect() != green.Rect() || green.Rect() != blue.Rect() || red.Rect() != blue.Rect()) return FALSE; if (!Create(red.Size(), 24)) return FALSE; BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); LPSTR lpDibHdrRed = (LPSTR) ::GlobalLock(red.m_hDib); LPSTR lpDibBitsRed = ::FindDIBBits(lpDibHdrRed); LPSTR lpDibHdrGreen = (LPSTR) ::GlobalLock(green.m_hDib); LPSTR lpDibBitsGreen = ::FindDIBBits(lpDibHdrGreen); LPSTR lpDibHdrBlue = (LPSTR) ::GlobalLock(blue.m_hDib); LPSTR lpDibBitsBlue = ::FindDIBBits(lpDibHdrBlue); CRect r(Rect()); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { COLORREF r; COLORREF g; COLORREF b; if (red.GetPixel(x, y, r, lpDibBitsRed) && green.GetPixel(x, y, g, lpDibBitsGreen) && blue.GetPixel(x, y, b, lpDibBitsBlue)) { COLORREF c = RGB(GetRValue(r), GetGValue(g), GetBValue(b)); bSuccess = bSuccess && SetPixel(x, y, c, lpDibBits); } else bSuccess = FALSE; } } GlobalUnlock((HGLOBAL) m_hDib); GlobalUnlock((HGLOBAL) red.m_hDib); GlobalUnlock((HGLOBAL) green.m_hDib); GlobalUnlock((HGLOBAL) blue.m_hDib); return bSuccess; } BOOL CDibImage::GetRedHistogram(int* RedChannel, int nSize) { if (m_hDib == NULL) return FALSE; for (int i=0; i<nSize; i++) RedChannel[i] = 0; ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int r = GetRValue(c); if (r < nSize) RedChannel[r]++; } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); return bSuccess; } BOOL CDibImage::GetGreenHistogram(int* GreenChannel, int nSize) { if (m_hDib == NULL) return FALSE; for (int i=0; i<nSize; i++) GreenChannel[i] = 0; ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int g = GetGValue(c); if (g < nSize) GreenChannel[g]++; } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); return bSuccess; } BOOL CDibImage::GetBlueHistogram(int* BlueChannel, int nSize) { if (m_hDib == NULL) return FALSE; for (int i=0; i<nSize; i++) BlueChannel[i] = 0; ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int b = GetBValue(c); if (b < nSize) BlueChannel[b]++; } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); return bSuccess; } BOOL CDibImage::GetHistogram(int* RedChannel, int nRedSize, int* GreenChannel, int nGreenSize, int* BlueChannel, int nBlueSize) { if (m_hDib == NULL) return FALSE; for (int i=0; i<nRedSize; i++) RedChannel[i] = 0; for (i=0; i<nGreenSize; i++) GreenChannel[i] = 0; for (i=0; i<nBlueSize; i++) BlueChannel[i] = 0; ASSERT(m_pWorkingArea); CRect r(m_pWorkingArea->BoundingRectangle()); BOOL bSuccess = TRUE; LPSTR lpDibHdr = (LPSTR) ::GlobalLock(m_hDib); LPSTR lpDibBits = ::FindDIBBits(lpDibHdr); for (int y=r.top; bSuccess && y<r.bottom; y++) { for (int x=r.left; bSuccess && x<r.right; x++) { if (m_pWorkingArea->PointInSelection(CPoint(x, y))) { COLORREF c; if (GetPixel(x, y, c, lpDibBits)) { int r = GetRValue(c); int g = GetGValue(c); int b = GetBValue(c); if (r < nRedSize) RedChannel[r]++; if (g < nGreenSize) GreenChannel[g]++; if (b < nBlueSize) BlueChannel[b]++; } else bSuccess = FALSE; } } } GlobalUnlock((HGLOBAL) m_hDib); return bSuccess; }